/**
 * Created by 黄健 on 2015-05-20.
 */

var instance;

var treeData = [];//定义全局树对象数据

//节点类型对象：顶上事件（T）、中间事件（M）、基本事件（X）、与门（YM）、
//或门（HM）、条件（C）、基本事件子类型省略事件（SLSJ）、正常事件（ZCSJ）
var treeNodeTypeObj = {
    "T":"T",
    "M":"M",
    "X":"X",
    "YM":"YM",
    "HM":"HM",
    "C":"C",
    "SLSJ":"SLSJ",
    "ZCSJ":"ZCSJ"
};

//全局样式对象
var mainStyle = {
    "connectorLineColor":"#096EBB"//连接线颜色
};

$(function(){

});

/**
 * 初始化拓扑图实例及外观设置
 */
(function(){

    /*if(window.localStorage){
        //localStorage.clear();
        if(!localStorage.getItem("mainStyle")){
            localStorage.setItem("mainStyle", JSON.stringify(mainStyle))
        }else{
            var o = JSON.parse(localStorage.getItem("mainStyle"));
            alert(o.connectorLineColor);
        }
    }else{
        alert("当前浏览器不支持localStorage");
    }*/

    instance = jsPlumb.importDefaults({
        DragOptions : { cursor: 'pointer', zIndex:2000 },
        EndpointStyles : [{ fillStyle:'#225588' }, { fillStyle:'#558822' }],
        Endpoints : [ [ "Dot", { radius:2 } ], [ "Dot", { radius: 2 } ]],
        ConnectionOverlays : [
            //[ "Arrow", { location:1 } ],//连接线箭头
            /*[ "Label", {
             label: "正在选择目标节点",
             //location:0.1,
             id:"label",
             cssClass:"aLabel"
             }]*/
        ]
    });

    //定义连接线的绘画样式
    var connectorPaintStyle = {
        lineWidth: 1,
        strokeStyle: mainStyle.connectorLineColor,
        joinstyle:"round",
        outlineColor: mainStyle.connectorLineColor,
        outlineWidth: 1
    };

    //定义鼠标悬浮在连接线上的时候的样式
    var connectorHoverStyle = {
        lineWidth: 2,
        strokeStyle: "#5C96BC",
        outlineWidth: 2,
        outlineColor:"white"
    };

    //定义鼠标悬浮在连接点上的时候的样式
    var endpointHoverStyle = {
        fillStyle:"#5C96BC",
        strokeStyle: "#5C96BC"
    };

    //给连接线绑定右键菜单事件
    instance.bind("contextmenu", function(component, originalEvent) {

        var sourceId = component.sourceId;
        var targetId = component.targetId;
        var sourceNodeKey = cutNodeDivId(sourceId);
        var targetNodeKey = cutNodeDivId(targetId);

        //判断目标节点是否是条件节点，如果是，那么就不给点击删除
        us.each(treeData, function(item, i){
            if(targetNodeKey == item.key){
                if(item.type == treeNodeTypeObj.C){
                    alert("由于目标节点为条件节点，因此不能点击删除，您可以在条件节点右键删除");
                    return false;
                }else{
                    if(confirm("是否确认删除此连接线？")){
                        if(item.key == targetNodeKey){
                            item.parentKey = "";
                        }
                        instance.detach(component);
                        return false;
                    }
                }
            }
        });

    });


    instance.bind("connection", function (connInfo, event) {

    });

    /*instance.bind("connectionDetached", function (component, originalEvent) {
        if(originalEvent){
            var C_TYPE = treeNodeTypeArray[5];

            var sourceId = component.sourceId;
            var targetId = component.targetId;
            var sourceNodeKey = cutNodeDivId(sourceId);
            var targetNodeKey = cutNodeDivId(targetId);

            for(var i=0; i<treeData.length; i++){
                if(treeData[i].key == targetNodeKey){
                    if(treeData[i].type == C_TYPE){
                        alert("由于目标节点为条件节点，因此不能点击删除，您可以在条件节点右键删除");
                        instance.connect({uuids:[sourceId+"Right", targetId+"Left"], editable: false});
                        return false;
                    }
                }
            }

            if(confirm("是否确认删除此连接线？")){
                for (var i=0; i<treeData.length; i++) {
                    if(treeData[i].key == targetNodeKey){
                        treeData[i].parentKey = "";
                    }
                }
                instance.detach(component);
                return false;
            }


            instance.connect({uuids:[component.sourceId+"Bottom", component.targetId+"Top"], editable: false});
        }
    });*/

    window.treeDrawUtil = {

        sourceEndpoint: {
            endpoint:"Dot",
            paintStyle:{
                strokeStyle:"#096EBB",
                fillStyle:"#096EBB",
                radius: 4,
                lineWidth:2
            },
            isSource:true,
            maxConnections:-1,
            //在这里可以通过设置stub来改变连接线折角的高度
            connector:[ "Flowchart", { stub:[8, 8], gap:3, cornerRadius:5, alwaysRespectStubs:true } ],
            connectorStyle: connectorPaintStyle,
            hoverPaintStyle: endpointHoverStyle,
            connectorHoverStyle: connectorHoverStyle,
            dragOptions:{},
            overlays:[
                [ "Label", {
                    location:[0.5, 1.5],
                    label:"",
                    cssClass:"endpointSourceLabel"
                } ]
            ]
        },

        targetEndpoint: {
            endpoint: "Dot",
            paintStyle: {
                strokeStyle:"#096EBB",
                fillStyle:"#096EBB",
                radius: 4,
                lineWidth:2
            },
            hoverPaintStyle: endpointHoverStyle,
            maxConnections:1,
            dropOptions:{ hoverClass:"hover", activeClass:"active" },
            isTarget:true,
            reattach: true,//重新接上
            overlays:[
                [ "Label", { location:[0.5, -0.5], label:"", cssClass:"endpointTargetLabel" } ]
            ],
            beforeDrop: function (e) {

                var sourceId = e.sourceId;
                var targetId = e.targetId;
                var sourceNodeKey = cutNodeDivId(sourceId);
                var targetNodeKey = cutNodeDivId(targetId);
                var $sourceNodeDiv = $("#"+sourceId);
                var $targetNodeDiv = $("#"+targetId);
                var sourceNodeType = $sourceNodeDiv.attr("data-nodeType");
                var targetNodeType = $targetNodeDiv.attr("data-nodeType");
                var targetNode = findTreeNode(targetNodeKey, treeData);
                //console.log("sourceNodeType:"+sourceNodeType+",targetNodeType:"+targetNodeType);

                if(targetNodeType != treeNodeTypeObj.YM && targetNodeType != treeNodeTypeObj.HM){
                    if(sourceNodeType != treeNodeTypeObj.YM && sourceNodeType != treeNodeTypeObj.HM){
                        alert(targetNode.name+"的上级节点必须是（与门）或（或门）");
                        return false;
                    }
                }

                us.each(treeData, function(item, i){
                    if(item.key == targetNodeKey){
                        item.parentKey = sourceNodeKey;
                    }
                });
                return true;//必须返回true才能正常连接
            }
        },

        initConnection: function(connection) {
            connection.bind("editCompleted", function(o) {
                //if (typeof console != "undefined")
                //console.log("connection edited. path is now ", o.path);
            });
        },

        addEndpoints: function(toId, sourceAnchors, targetAnchors) {
            for (var i = 0; i < sourceAnchors.length; i++) {
                var sourceUUID = toId + sourceAnchors[i];
                instance.addEndpoint(toId, this.sourceEndpoint, { anchor:sourceAnchors[i], uuid:sourceUUID });
            }
            for (var j = 0; j < targetAnchors.length; j++) {
                var targetUUID = toId + targetAnchors[j];
                instance.addEndpoint(toId, this.targetEndpoint, { anchor:targetAnchors[j], uuid:targetUUID });
            }
        }

    };


})();

/**
 * 生成节点DIV
 * @param _nodeData
 * @returns {string}
 */
function createNodeDiv(_nodeData) {

    var nodeDivClass = "node";
    var nodeDivMarkHtml = "<div class='nodeMark'>"+_nodeData.number+"</div>";
    var imgHtml = "";

    var nodeType = _nodeData.type;
    var nodeSubType = _nodeData.subType;
    if(nodeType == treeNodeTypeObj.YM || nodeType == treeNodeTypeObj.HM){
        switch (nodeType) {
            case treeNodeTypeObj.YM:
                imgHtml = "<img src='resources/images/yumen.png' style='width: 100%; height: 100%;'>";
                break;
            case treeNodeTypeObj.HM:
                imgHtml = "<img src='resources/images/huomen.png' style='width: 100%; height: 100%;'>";
                break;
        }
        nodeDivClass = "node node-yhm";
        nodeDivMarkHtml = "";
    }else if(nodeType == treeNodeTypeObj.X){
        //判断是否有子类型并且
        if(nodeSubType != "" && nodeSubType == treeNodeTypeObj.SLSJ){
            imgHtml = "<img src='resources/images/diamond.png' style='width: 100%; height: 100%;'>";
            nodeDivClass = "node node-x-slsj";
            //nodeDivMarkHtml = "";
        }else if(nodeSubType != "" && nodeSubType == treeNodeTypeObj.ZCSJ){
            imgHtml = "<img src='resources/images/zcsj.png' style='width: 100%; height: 100%;'>";
            nodeDivClass = "node node-x-zcsj";
        }else{
            imgHtml = "<img src='resources/images/circle.png' style='width: 100%; height: 100%;'>";
            nodeDivClass = "node node-x";
            //nodeDivMarkHtml = "";
        }
    }else if(nodeType == treeNodeTypeObj.C){
        imgHtml = "<img src='resources/images/hexagon.png' style='width: 100%; height: 100%;'>";
        nodeDivClass = "node node-c";
    }

    var nodeDivId = obtainNodeDivId(_nodeData);
    return "<div id='"+nodeDivId+"' title='"+_nodeData.name+"' data-nodeKey='"+_nodeData.key+"' class='"+nodeDivClass+"' data-nodeType='"+_nodeData.type+"' " +
        "style='left: "+_nodeData.position[0]+"px; top: "+_nodeData.position[1]+"px;'" +
        "ondblclick='nodeDbClick(this)'>" + imgHtml +
            //"<img src='resources/images/circle.png' style='width: 100%; height: 100%;'/>"+
            "<span class='nodeNameSpan'>"+cutNodeName(_nodeData.name)+"</span>"+nodeDivMarkHtml+
            "<div class='nodeNameSpanInputContainer' style='position: absolute; left: 2px; top: 2px; display: none;'>" +
                //"<input type='text' placeholder='请输入节点名称'>"+
                "<div class='input-group input-group-sm' style='width: 250px;'>"+
                    "<input type='text' class='form-control' placeholder='请输入节点名称'>"+
                    "<span class='input-group-btn'>" +
                        "<button class='btn btn-primary' type='button' " +
                            "onclick='submitNodeNameSpanInput(&apos;"+nodeDivId+"&apos;)'>确定</button>"+
                        "<button class='btn btn-danger' type='button' " +
                            "onclick='closeNodeNameSpanInputContainer(&apos;"+nodeDivId+"&apos;)'>取消</button>"+
                    "</span>"+
                "</div>"+
            "</div>"+
        "</div>";

}

/**
 * 增加新的节点到画布中
 * @param _nodeData 节点数据
 * 数据结构：
 * var nodeData = {
                type: "",
                subType: "",//子类型，例如基本事件下的省略事件
                key: "",
                name: "",
                number: "",//编号
                position: ["", ""],
                size: {"width":"", "height":""},
                parentKey: ""
            };
 * @param _isFromBuild 是否来自构建方法buildTree，如果传入true，那么内部就不对编号进行处理
 * @returns {string} 返回新添加的节点DIV ID
 */
function addNode(_nodeData, _isFromBuild){

    //在加入节点前先做一次校验（这段代码可以考虑封装起来，专门用于校验数据的完整性与正确性）
    if(!us.isEmpty(treeData)){
        if(_nodeData.type == treeNodeTypeObj.T){
            var flag = false;
            us.each(treeData, function(item, i){
                if(item.type == treeNodeTypeObj.T){
                    flag = true;

                }
            });
            if(flag){
                alert("顶上事件只能有一个，不能重复添加");
                return false;
            }
        }
    }

    if(_isFromBuild){
        treeData.push(_nodeData);
    }else{
        treeData.push(nodeNumberHandle(_nodeData));
    }

    //如果是顶上事件，就更新他的canvasSize属性
    if(_nodeData.type == treeNodeTypeObj.T){
        updateTreeDataCanvasSize();
    }

    $accidentTreeCanvas.append(createNodeDiv(_nodeData));
    var nodeDivId = obtainNodeDivId(_nodeData);

    //注册节点nodeNameSpan文本改变之后触发的监听事件（不支持IE8）
    //$("#"+nodeDivId).find(".nodeNameSpan").bind("DOMNodeInserted", function(e){});

    if(_nodeData.type != treeNodeTypeObj.YM
        && _nodeData.type != treeNodeTypeObj.HM){
        //给新增加的节点注册resizable事件
        /*$("#"+nodeDivId).resizable({
            handles: "se",
            //cancel: ".jsplumb-draggable, ._jsPlumb_endpoint_anchor",
            //autoHide: true,
            maxHeight: 200,
            maxWidth: 200,
            minHeight: 40,
            minWidth: 80,
            resize: function(event, ui){
                instance.repaintEverything();
            },
            stop: function(event, ui){
                var nodeDivId = ui.element[0].id;
                var nodeKey = cutNodeDivId(nodeDivId);

                for(var i=0; i<treeData.length; i++){
                    if(treeData[i].key == nodeKey){
                        treeData[i].size.width = $(this).css("width").replace("px","");
                        treeData[i].size.height = $(this).css("height").replace("px","");
                    }
                }
            }
        });*/
    }

    //如果节点的size属性中的宽度与高度没有值，那么就给它设置当前添加到画布中的节点DIV的宽度与高度
    //否则就通过读取节点的size属性来设置DIV的宽度与高度
    if(_nodeData.size.width == "" && _nodeData.size.height == ""){
        for(var i=0; i<treeData.length; i++){
            if(treeData[i].key == cutNodeDivId(nodeDivId)){
                treeData[i].size.width = $("#"+nodeDivId).css("width").replace("px","");
                treeData[i].size.height = $("#"+nodeDivId).css("height").replace("px","");
            }
        }
    }else{
        for(var i=0; i<treeData.length; i++){
            if(treeData[i].key == cutNodeDivId(nodeDivId)){
                $("#"+nodeDivId).css("width", treeData[i].size.width+"px");
                $("#"+nodeDivId).css("height", treeData[i].size.height+"px");
            }
        }
    }

    //节点拖拽鼠标放下事件，实时更新节点坐标
    $("#"+nodeDivId).mouseup(function(e){
        var nodeDivId = e.currentTarget.id;
        $nodeActive = $("#"+nodeDivId);

        if(selectedNodes.length > 0){
            for(var i=0; i<selectedNodes.length; i++){
                updateNodeDivPosition($("#"+selectedNodes[i].id));
            }
        }else{
            updateNodeDivPosition($nodeActive);
        }

    });

    //给节点绑定右键菜单
    $("#"+nodeDivId).bind("contextmenu", function(e){
        //先删除右键菜单中的（添加条件）项
        $treeNodeContentMenu.children("ul").find("#addConditionMenuItem").remove();

        //遍历其他的节点，如果存在nodeActive样式类，则将其删除
        $accidentTreeCanvas.children(".node").each(function(){
            if($(this).hasClass("nodeActive")){
                $(this).removeClass("nodeActive");
                $(this).css("z-index", "25");
            }
        });
        $(this).addClass("nodeActive");
        $(this).css("z-index", "30");
        $accidentTreeCanvas.blur();

        if(e.which == 3){
            //遍历判断当前选中节点是否是与门或者或门，如果是，则在右键菜单中添加：添加条件
            for(var i=0;i<treeData.length; i++){
                if(treeData[i].key == cutNodeDivId(e.currentTarget.id)){
                    if(treeData[i].type == treeNodeTypeObj.YM || treeData[i].type == treeNodeTypeObj.HM){
                        //判断右键菜单中是否存在（添加条件）菜单项
                        if($treeNodeContentMenu.children("ul").find("#addConditionMenuItem").length == 0){
                            $treeNodeContentMenu.children("ul")
                                .append("<a id='addConditionMenuItem' class='list-group-item' href='javascript:;' onclick='addConditionNode(&apos;"+e.currentTarget.id+"&apos;)'><i class='fa fa-plus fa-lg'></i> 添加条件</a>");
                        }
                    }
                }
            }

            var mouseCoord = getPositionByObj(e, "accidentTreeCanvas");
            var x = parseInt(mouseCoord.x);
            var y = parseInt(mouseCoord.y);
            //alert("x="+x+",y="+y);
            $treeNodeContentMenu.show();
            $treeNodeContentMenu.css("left", x+"px");
            $treeNodeContentMenu.css("top", y+"px");
            return false;
        }
    });

    //给节点绑定单击事件监听
    $("#"+nodeDivId).mousedown(function (e) {
        //先删除右键菜单中的（添加条件）项
        $treeNodeContentMenu.children("ul").find("#addConditionMenuItem").remove();

        //遍历其他的节点，如果存在nodeActive样式类，则将其删除
        $accidentTreeCanvas.children(".node").each(function(){
            if($(this).hasClass("nodeActive")){
                $(this).removeClass("nodeActive");
                $(this).css("z-index", "25");
            }
        });
        $(this).addClass("nodeActive");
        $(this).css("z-index", "30");
        $accidentTreeCanvas.blur();

        if(e.which == 1){
            if(e.target.localName === "input"){

                return true;
            }else{
                var nodeData = findTreeNode(cutNodeDivId(e.currentTarget.id), treeData);
                //var $nodeActive = $("#"+e.currentTarget.id);//得到当前激活的节点
                $("#nodeKeyInput").val(nodeData.key);
                $("#nodeNameInput").val(nodeData.name);
                $("#nodeTypeInput").val(nodeData.type);
                $("#nodeNumberInput").val(nodeData.number);
                $("#nodeWidthInput").val(nodeData.size.width);
                $("#nodeHeightInput").val(nodeData.size.height);
                $("#nodeXInput").val(nodeData.position[0]);
                $("#nodeYInput").val(nodeData.position[1]);
                //console.info(JSON.stringify(nodeData));
                if(selectedNodes.length > 0 && !$("#"+ e.currentTarget.id).hasClass("ui-selected")){
                    for(var i = 0; i<selectedNodes.length; i++){
                        $("#"+selectedNodes[i].id).removeClass("ui-selected");
                        instance.removeFromDragSelection(selectedNodes[i]);
                    }
                    selectedNodes = [];//清空selectedNodes
                }
                $treeNodeContentMenu.hide();
                return false;
            }
        }
    });

    //instance.draggable($("#"+nodeDivId));//重新激活节点的拖拽
    jsPlumb.draggable(jsPlumb.getSelector(".node"), { grid: [5, 5] });//重新激活节点的拖拽

    //判断节点类型添加连接点
    switch (_nodeData.type) {
        case treeNodeTypeObj.T:
            treeDrawUtil.addEndpoints(nodeDivId, ['Bottom'], []);
            break;
        case treeNodeTypeObj.M:
            treeDrawUtil.addEndpoints(nodeDivId, ['Bottom'], ['Top']);
            break;
        case treeNodeTypeObj.X:
            treeDrawUtil.addEndpoints(nodeDivId, [], ['Top']);
            break;
        case treeNodeTypeObj.YM:
            treeDrawUtil.addEndpoints(nodeDivId, ['Bottom'], ['Top']);
            break;
        case treeNodeTypeObj.HM:
            treeDrawUtil.addEndpoints(nodeDivId, ['Bottom'], ['Top']);
            break;
        case treeNodeTypeObj.C:
            treeDrawUtil.addEndpoints(nodeDivId, [], ['Left']);
            break;
        default:
            break;
    }

    return nodeDivId;
}

/**
 * 更新记录节点DIV坐标
 * @param _nodeObj
 */
function updateNodeDivPosition(_nodeObj){
    var left = _nodeObj.css("left").replace("px","");
    var top = _nodeObj.css("top").replace("px","");
    for (var i=0; i<treeData.length; i++) {
        if(treeData[i].key == _nodeObj.attr("data-nodeKey")){
            treeData[i].position[0] = left;
            treeData[i].position[1] = top;
        }
    }
}

/**
 * 节点编号处理
 * @param _nodeData 节点数据
 * @returns {*} 返回处理之后的节点数据
 */
function nodeNumberHandle(_nodeData){

    var numHandle = function(_type){
        var maxNumber = 0;
        us.each(treeData, function(item, i){
            if(item.type == _type){
                var n = parseInt(item.number.replace(_type, ""));
                if(n > maxNumber){
                    maxNumber = n;
                }
                if(item.name === _nodeData.name){
                    _nodeData.number = item.number;
                    return _nodeData;
                }
            }
        });
        _nodeData.number = _nodeData.type+""+(maxNumber+1);
    };

    var nodeType = _nodeData.type;
    switch (nodeType){
        case treeNodeTypeObj.T:
            _nodeData.number = "T";
            break;
        case treeNodeTypeObj.M:
            numHandle(treeNodeTypeObj.M);
            break;
        case  treeNodeTypeObj.X:
            numHandle(treeNodeTypeObj.X);
            break;
        case treeNodeTypeObj.C:
            numHandle(treeNodeTypeObj.C);
            break;
    }

    return _nodeData;
}

/**
 * 添加条件节点
 * @param _sourceNodeDivId 源节点DIV ID
 */
function addConditionNode(_sourceNodeDivId){

    $treeNodeContentMenu.hide();

    for(var i=0; i<treeData.length; i++){
        if(treeData[i].parentKey == cutNodeDivId(_sourceNodeDivId)
            && treeData[i].type == treeNodeTypeObj.C){
            alert("此节点已经存在一个条件节点，不能再添加");
            return false;
        }
    }

    var nodeName = showPrompt();
    if(nodeName == null){
        return false;
    }

    treeDrawUtil.addEndpoints(_sourceNodeDivId, ['Right'], []);//给源节点添加右侧连接点
    var left = $("#"+_sourceNodeDivId).css("left").replace("px","");
    var top = $("#"+_sourceNodeDivId).css("top").replace("px","");
    var cNodeData = {
        type: "C",
        subType: "",
        key: ""+createUuid(),
        name: nodeName,
        number: "",//编号
        position: [parseInt(left)+80, top],
        size: {"width":"", "height":""},
        parentKey: ""
    };

    var nodeDivId = addNode(nodeNumberHandle(cNodeData));
    var newNodeKey = cutNodeDivId(nodeDivId);//新添加的节点Key

    for (var i=0; i<treeData.length; i++) {
        if(treeData[i].key == newNodeKey){
            treeData[i].parentKey = cutNodeDivId(_sourceNodeDivId);
        }
    }

    instance.connect({uuids:[_sourceNodeDivId+"Right", nodeDivId+"Left"], editable: false});
}

/**
 * 构建事故树
 * @param _treeData 数据串
 */
function buildTree(_treeData){

    _treeData = JSON.parse(_treeData);

    /**
     * 检查数据串中的T节点中是否存在canvasSize属性，存在的话则根据值设置画布大小
     */
    us.each(_treeData, function(item, i){
        if(item.type == treeNodeTypeObj.T
            && item.hasOwnProperty("canvasSize")){
            $accidentTreeCanvas.css("width", _treeData[i].canvasSize[0]+"px");
            $accidentTreeCanvas.css("height", _treeData[i].canvasSize[1]+"px");
        }
    });

    //加载前先清空画布中的所有节点
    clearTree();

    //开始遍历并先将所有节点添加至画布
    us.each(_treeData, function(item, i){
        addNode(item, true);
    });

    //遍历全局数对象并添加连线
    us.each(treeData, function(item, i){
        if(item.parentKey != "" && item.type != treeNodeTypeObj.C) {
            var curId = item.type + "-" + item.key;
            var parentNode = findTreeNode(item.parentKey, treeData);
            var parentId = parentNode.type + "-" + parentNode.key;

            instance.connect({uuids:[parentId+"Bottom", curId+"Top"], editable: false});
        }else if(item.type == treeNodeTypeObj.C){//如果节点类型为条件节点C
            var curId = item.type + "-" + item.key;
            var parentNode = findTreeNode(item.parentKey, treeData);
            var parentId = parentNode.type + "-" + parentNode.key;
            treeDrawUtil.addEndpoints(parentId, ['Right'], []);//给父节点（与门、或门）添加右侧连接点
            instance.connect({uuids:[parentId+"Right", curId+"Left"], editable: false});
        }
    });

}

/**
 * 节点双击事件
 * @param event
 */
function nodeDbClick(event){
    var nodeId = cutNodeDivId(event.id);
    var node = findTreeNode(nodeId, treeData);
    if(node.type != treeNodeTypeObj.YM && node.type != treeNodeTypeObj.HM){
        var $nodeDiv = $("#"+event.id);
        var $nodeNameSpan = $nodeDiv.find(".nodeNameSpan");
        var $nodeNameSpanInputContainer = $nodeDiv.find(".nodeNameSpanInputContainer");
        var $nodeNameSpaninput = $nodeNameSpanInputContainer.find("input");
        $nodeNameSpan.hide();
        $nodeNameSpanInputContainer.show("fast");
        $nodeNameSpaninput.val("").focus().val(node.name);
        $nodeNameSpaninput.on("keypress", function(event){
            var value = replaceBlank(event.target.value);
            if(event.keyCode == 13) {
                updateNodeNameHandler($nodeDiv, value);
                $nodeNameSpan.show();
                $nodeNameSpanInputContainer.hide("fast");
            }
        });
    }
}


function submitNodeNameSpanInput(_nodeActiveDivId){
    var $nodeDiv = $("#"+_nodeActiveDivId);
    var $nodeNameSpan = $nodeDiv.find(".nodeNameSpan");
    var $nodeNameSpanInputContainer = $nodeDiv.find(".nodeNameSpanInputContainer");
    var $nodeNameSpaninput = $nodeNameSpanInputContainer.find("input");
    var result = updateNodeNameHandler($nodeDiv, $nodeNameSpaninput.val());
    if(result != null && result == false){

    }else{
        $nodeNameSpan.show();
        $nodeNameSpanInputContainer.hide("fast");
    }
}

/**
 * 隐藏节点名称输入框组
 * @param _nodeActiveDivId
 */
function closeNodeNameSpanInputContainer(_nodeActiveDivId){
    var $nodeDiv = $("#"+_nodeActiveDivId);
    var $nodeNameSpan = $nodeDiv.find(".nodeNameSpan");
    var $nodeNameSpanInputContainer = $nodeDiv.find(".nodeNameSpanInputContainer");
    $nodeNameSpan.show();
    $nodeNameSpanInputContainer.hide("fast");
}

/**
 * 删除节点
 */
function removeTreeNode(event){

    $treeNodeContentMenu.hide();//隐藏节点右键菜单
    var $nodeActive = $(".nodeActive");//获取当前激活的节点对象
    var nodeDivId = $nodeActive.attr("id");//获取节点ID
    var nodeKey = cutNodeDivId(nodeDivId);//截取DIV ID，得到节点的Key

    var curNode = findTreeNode(nodeKey, treeData);
    if(curNode.type == treeNodeTypeObj.T && treeData.length > 1){
        alert("顶上事件下存在其他节点，不可删除");
        return false;
    }

    var remove = function(_obj){
        //处理删除的节点为条件节点的情况
        if(_obj.attr("data-nodeType") == treeNodeTypeObj.C){
            var curNode = findTreeNode(_obj.attr("data-nodeKey"), treeData);
            for(var i=0;i<treeData.length; i++){
                if(treeData[i].key == curNode.parentKey){
                    var parentDivId = treeData[i].type+"-"+treeData[i].key;//条件节点的父节点DIV ID
                    //删除父节点右侧的连接点，deleteEndpoint接收的参数为UUID（DIV ID加上方向）
                    instance.deleteEndpoint(parentDivId+"Right");
                }
            }
        }

        treeData = deleteNodeData(_obj.attr("data-nodeKey"), treeData);//从树对象数据中删除此节点数据
        instance.removeAllEndpoints(_obj.attr("id"));
        _obj.remove();
    };

    var confirmStr = "";
    if(selectedNodes.length > 0){
        confirmStr = "确认删除选中的"+selectedNodes.length+"个节点吗？";
    }else{
        confirmStr = "确认删除此节点吗？";
    }
    if(confirm(confirmStr)){
        if(selectedNodes.length > 1){
            var flag = true;
            us.each(selectedNodes, function(item, key){
                if($(item).attr("data-nodeType") == treeNodeTypeObj.T){
                    alert("顶上事件下还存在其他节点没有被选中，因此顶上事件将不会被删除");
                    flag = false;
                }
            });
            if(flag){
                for(var i=0; i<selectedNodes.length; i++){
                    remove($("#"+selectedNodes[i].id));
                }
            }
        }else{
            remove($nodeActive);
        }

        return false;
    }

}

/**
 * 清空画布
 */
function clearTree(){
    jsPlumb.empty("accidentTreeCanvas");
    $accidentTreeCanvas.html("");
    treeData = [];
    $atcContentMenu.hide();
}

/**
 * 检查数据的正确性
 * @returns {boolean} 返回校验结果
 * @param _alertSuccess 是否弹出校验成功提示，0：不弹出，1：弹出
 */
function checkTreeData(_alertSuccess){
    $atcContentMenu.hide();
    var flag = true;
    var msg = "数据正确性校验结果：成功！";

    if(treeData.length == 0){
        flag = false;
        msg = "您还没有绘制事故树，请先进行绘制！";
    }

    try{
        us.each(treeData, function (item, i) {
            if(item.type == treeNodeTypeObj.YM || item.type == treeNodeTypeObj.HM){
                var parentNode = findTreeNode(item.parentKey, treeData);
                var childs = findChilds(item.key, treeData);
                if(childs.length < 2){
                    flag = false;
                    msg = "数据正确性校验结果：失败！结果分析：事件"+parentNode.name+"下必须有两个以上的事件关联。"
                }
            }else if(item.type == treeNodeTypeObj.M){
                var childs = findChilds(item.key, treeData);
                if(childs.length < 1){
                    flag = false;
                    msg = "数据正确性校验结果：失败！结果分析："+item.name+"事件下没有其他事件关联。"
                }
            }else if(item.type == treeNodeTypeObj.T){
                var childs = findChilds(item.key, treeData);
                if(childs.length < 1){
                    flag = false;
                    msg = "数据正确性校验结果：失败！结果分析：事件"+item.name+"未画完整。"
                }
            }
        });
    }catch (e){
        flag = false;
        msg = "数据正确性校验结果：失败！结果分析：数据结构错误，校验发生异常，异常代码："+e.toString();
    }

    if(_alertSuccess == "1"){
        alert(msg);
    }
    return flag;
}

/**
 * 更新treeData中顶上节点的canvasSize属性
 */
function updateTreeDataCanvasSize(){

    if(treeData.length > 0){
        us.each(treeData, function(item, i){
            if(item.type == treeNodeTypeObj.T){
                var width = $accidentTreeCanvas.css("width").replace("px","");
                var height = $accidentTreeCanvas.css("height").replace("px","");
                item.canvasSize = [""+width, ""+height];
            }
        });
    }

}

/**
 * 加载数据串按钮点击触发
 */
function loadTreeData(){
    try{
        buildTree($("#treeDataTextarea").val());
        $("#loadTreeDataModal").modal("hide");
    }catch (e){
        alert("加载失败，可能原因：数据串格式不正确");
    }
}

/**
 * 截取节点DIV的ID，取消前缀（前缀为节点类型加上一个中划线：T-），然后返回一个UUID，用于在数据串中查询使用
 * @param _nodeDivId
 * @returns {string}
 */
function cutNodeDivId(_nodeDivId){
    return _nodeDivId.substring(_nodeDivId.indexOf("-")+1, _nodeDivId.length);
}

/**
 * 根据Key获取节点对象
 * @param _key
 * @param _treeData 数据串
 * @returns {*}
 */
function findTreeNode(_key, _treeData){
    var nodeData = null;
    us.each(_treeData, function(item, key){
        if(_key == item.key){
            nodeData = item;
        }
    });
    return nodeData;
}

/**
 * 查找子节点数组
 * @param _key
 * @param _treeData
 * @returns {Array}
 */
function findChilds(_key, _treeData){
    var childs = [];
    for(var i=0; i<_treeData.length; i++){
        if(_treeData[i].parentKey == _key){
            childs.push(_treeData[i])
        }
    }
    return childs;
}

/**
 * 根据类型获取节点数组
 * @param _type
 * @param _treeData
 * @returns {Array}
 */
function findTreeNodesByType(_type, _treeData){
    var nodeDatas = [];
    us.each(_treeData, function(item, key){
        if(_type == item.type){
            nodeDatas.push(item);
        }
    });
    return nodeDatas;
}

/**
 * 删除树对象数据中对应key的节点对象
 * @param _key
 */
function deleteNodeData(_key, _treeData){
    for (var i=0; i<_treeData.length; i++) {
        var cur_treeNode = _treeData[i];
        if (cur_treeNode.key == _key) {
            _treeData.splice(i, 1);
        }
    }
    return _treeData;
}

/**
 * 生成节点的 DIV ID
 * @param _nodeData
 * @returns {string}
 */
function obtainNodeDivId(_nodeData) {
    return _nodeData.type.toUpperCase() + '-' + transferKey(_nodeData.key);
}

function transferKey(key) {
    return key.replace(/\./g, 'ZZZ');
}

/**
 * 生成UUID字符串
 * @returns {string}
 */
function createUuid() {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}
